#include "OpencvMo.h"
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include<QDebug>
using namespace cv;
using namespace std;
OpencvMo::OpencvMo(QObject *parent):QObject(parent){}
Point sp(-1, -1);
Point ep(-1, -1);
Mat temp;
void onChangeTrackBarLights(int pos, void* userdata);
void onChangeTrackBarConstra(int pos, void* userdata);
// 自定义 ImageProvider 类


Mat OpencvMo::opdationDemo(Mat &image) {

   // imshow("picture", image);
    Mat dst;
    Mat m = Mat::zeros(image.size(), image.type());
    m = Scalar(3,3, 3);

    multiply(image,m,dst);

    //add(image, m, dst);
    //subtract(image, m, dst);
    //divide(image, m, dst);
    //imshow("test", dst);
    return dst;
}
//TrackBar发生改变的回调函数
// 回调函数

void OpencvMo::colorstyleDemo(Mat& image) {

    int colomap[] = {

    COLORMAP_AUTUMN,
        COLORMAP_BONE,
        COLORMAP_JET,
        COLORMAP_WINTER,
        COLORMAP_RAINBOW,
        COLORMAP_OCEAN,
        COLORMAP_SUMMER,
        COLORMAP_SPRING,
        COLORMAP_COOL,
        COLORMAP_HSV,
        COLORMAP_PINK,
        COLORMAP_HOT,
        COLORMAP_PARULA,
        COLORMAP_MAGMA,
        COLORMAP_INFERNO,
        COLORMAP_PLASMA,
        COLORMAP_VIRIDIS,
        COLORMAP_CIVIDIS,
        COLORMAP_TWILIGHT,
        COLORMAP_TWILIGHT_SHIFTED,
        COLORMAP_TURBO,
        COLORMAP_DEEPGREEN,


};
Mat dst;
int index = 0;
while (true)
{
    int c = waitKey(1000);
    if (c == 27)
    {
        break;
    }
    applyColorMap(image, dst, colomap[index % 21]);
    index++;
    imshow("颜色风格", dst);


}

}
Mat OpencvMo::cvtColorDemo(Mat& image) {

    Mat hsv;
    cvtColor(image, hsv, COLOR_BGR2HSV);
    Mat mask;
    inRange(hsv, Scalar(100,43,46), Scalar(124,255,255), mask);
    //imshow("结果1", mask);
    Mat reback = Mat::zeros(image.size(), image.type());
    reback = Scalar(40, 40, 200);//背景红色画布

    bitwise_not(mask, mask);//画布取反
    //imshow("结果2", mask);
    image.copyTo(reback, mask);//拷贝非0的值到红色画布
    //imshow("结果3", reback);

    return reback;

}
void OpencvMo::pixstaticDemo(Mat& image) {

    double minv, maxv;
    Point minLoc, macLoc;
    vector<Mat> mv;
    split(image, mv);
    for (int i = 0; i < mv.size(); i++)
    {
        minMaxLoc(mv[i], &minv, &maxv, &minLoc, &macLoc, noArray()); // 对每个通道调用minMaxLoc
        cout << "通道 " << i << " 最小值: " << minv << " 最大值: " << maxv << endl;
    }

    Mat mean, stddev;
    meanStdDev(image, mean, stddev);
    cout << "mean val" << mean << "stddev val" << stddev << endl;
}
void OpencvMo::drawDemo(Mat& image) {
    Rect rect;
    rect.x = 300;
    rect.y = 300;

    rect.width = 200;
    rect.height = 200;
    Mat bg = Mat::zeros(image.size(), image.type());
    rectangle(bg, rect, Scalar(0, 0, 255), -1, 8, 0);
    circle(bg, Point(300, 300), 15, Scalar(255, 0, 0), -1, 8, 0);
    line(bg, Point(300, 300), Point(500, 500), Scalar(0, 255, 0), 4, LINE_AA, 0);
    RotatedRect rrt;//绘制椭圆
    rrt.center = Point(300, 300);
    rrt.size = Size(100, 200);
    rrt.angle = 90;

    ellipse(image, rrt, Scalar(0, 255, 255), 2, 8);
    Mat dst;
    addWeighted(image, 0.7, bg, 0.3, 0, dst);

    imshow("绘制", dst);


}
void OpencvMo::randomDemo(){

    Mat canvas = Mat::zeros(Size(512, 512), CV_8UC3);
    RNG rng(12345);//随机数
    int w = canvas.cols;
    int h = canvas.rows;
    while (true)
    {
        int c = waitKey(100);
        if (c == 27)
        {
            break;
        }
        int x1 = rng.uniform(0, w);//随机范围
        int y1 = rng.uniform(0,h);
        int x2 = rng.uniform(0, w);
        int y2 = rng.uniform(0, h);
        int b= rng.uniform(0, 255);
        int g = rng.uniform(0, 255);
        int r = rng.uniform(0, 255);
        canvas = Scalar(0, 0, 0);
        line(canvas, Point(x1, y1), Point(x2, y2), Scalar(b, g, r), 2, LINE_8, 0);
        imshow("随机演示", canvas);
        cout << "hahah" << endl;
    }



}
void OpencvMo::poly_drawDemo() {
    Mat canvas = Mat::zeros(Size(512, 512), CV_8UC3);
    Point p1(100, 100);
    Point p2(350, 100);
    Point p3(450, 280);
    Point p4(320, 450);
    Point p5(80, 400);
    std::vector<Point> pts;
    pts.push_back(p1);
    pts.push_back(p2);
    pts.push_back(p3);
    pts.push_back(p4);
    pts.push_back(p5);
    //fillPoly(canvas, pts,Scalar(255, 0, 0), 8, 0);



    //polylines(canvas, pts, true, Scalar(255, 255, 0), LINE_AA , 0);

    std::vector<std::vector<Point>> contours;
    contours.push_back(pts);
    drawContours(canvas, contours, -1,Scalar(255,0,0),-1);
    imshow("多边型", canvas);
}
Mat OpencvMo::onChangeTrackBarConstra(int pos, Mat& image)
{
     qDebug()<<"滑动1";
    Mat src = image;
    Mat dst = Mat::zeros(src.size(), src.type());
    Mat m = Mat::zeros(src.size(), src.type());
    double con_val = pos /75.0;
    qDebug()<<"滑动2";
    addWeighted(src, con_val, m, 0, pos, dst);
     qDebug()<<"滑动3";
    //imshow("调整", dst);
    return dst;
}
static void on_draw(int event, int x, int y, int flags, void* userdata)
{
    Mat src = *(Mat*)(userdata);
    if (event == EVENT_LBUTTONDOWN)
    {
        sp.x = x;
        sp.y = y;
        cout << sp << endl;

    }
    else if (event == EVENT_LBUTTONUP)
    {

        ep.x = x;
        ep.y = y;
        int dx = ep.x - sp.x;
        int dy = ep.y - sp.y;
        if (dx > 0 && dy > 0) {
            Rect box(sp.x, sp.y, dx, dy);
            temp.copyTo(src);
            imshow("roi区域", src(box));
            rectangle(src, box, Scalar(0, 0, 255), 2, 8, 0);
            imshow("鼠标绘制", src);
            sp.x = -1;
            sp.y = -2;
        }
    }
    else if (event == EVENT_MOUSEMOVE)
    {
        if (sp.x > 0 && sp.y > 0)
        {

            ep.x = x;
            ep.y = y;
            int dx = ep.x - sp.x;
            int dy = ep.y - sp.y;
            if (dx > 0 && dy > 0)
            {
                Rect box(sp.x, sp.y, dx, dy);
                temp.copyTo(src);
                rectangle(src, box, Scalar(0, 0, 255), 2, 8, 0);
                imshow("鼠标绘制", src);

            }

        }


    }
}
void OpencvMo::mouse_draw(Mat & image)
{
    namedWindow("鼠标绘制", WINDOW_AUTOSIZE);
    setMouseCallback("鼠标绘制", on_draw, (void*)(&image));
    imshow("鼠标绘制", image);
    temp = image.clone();
}

void OpencvMo::resize_demo(Mat& image)
{
    Mat zoomin,zooout;

    int h = image.rows;
    int w = image.cols;

    resize(image, zoomin, Size(w / 2, h / 2), 0, 0, INTER_LINEAR);
    imshow("zoomin", zoomin);

    resize(image, zooout, Size(w * 1.5, h * 1.5), 0, 0, INTER_LINEAR);
    imshow("zooout", zooout);



}
void OpencvMo::flip_demo(Mat& image)
{
    Mat dst;
    flip(image, dst, 0);//上下
    //flip(image, dst,1);//左右
    //flip(image, dst, -1);//180
    imshow("翻转",dst);


}
void OpencvMo::rotato_demo(Mat& image)
{
    Mat dst, M;
    int w=image.cols;
    int h=image.rows;

    M = getRotationMatrix2D(Point2f(w /2, h /2), 45, 1.0);//中心点选择45

    double cos = abs(M.at<double>(0,0));

    double sin = abs(M.at<double>(0,1));

    int nw = cos * w + sin * h;
    int nh = sin * w + cos * h;

    M.at<double>(0,2)+= (nw / 2 - w / 2);
    M.at<double>(1,2)+=(nh / 2 - h / 2);
    warpAffine(image, dst,M,Size(nw,nh),INTER_LINEAR,0,Scalar(255,0,0));
    imshow("旋转", dst);


}
Mat OpencvMo::blur_demo(Mat& image) {
    /*Mat dst;
    blur(image, dst, Size(3, 3), Point(-1, -1));
    //imshow("图像模糊", dst);
    Mat dst2;
    GaussianBlur(image, dst2, Size(0, 0), 1);
    //imshow("高斯模糊", dst2);*/
    Mat dst3;
     qDebug()<<"1";
    bilateralFilter(image, dst3, 0, 200, 10);
      qDebug()<<"滑动";
    //imshow("高斯双边模糊",dst3);
    return dst3;
}
/*void QuickDemo2::face_detect_demo(Mat& image) {



        // 加载人脸分类器
        cv::CascadeClassifier faceCascade;

        //分类器文件下载地址: https://github.com/opencv/opencv/tree/master/data/haarcascades
        //在OpenCV的源码目录下其实也有（opencv\build\etc\haarcascades）。
        //下载后放到C盘根目录即可.
        faceCascade.load("D:/opencv/build/etc/haarcascades/haarcascade_frontalface_alt2.xml");

        // 打开摄像头
        cv::VideoCapture capture(0);
        if (!capture.isOpened())
        {
            std::cout << "无法打开摄像头" << std::endl;
            return ;
        }

        // 创建窗口
        cv::namedWindow("Face Detection", cv::WINDOW_NORMAL);

        while (true)
        {
            cv::Mat frame;
            capture >> frame; // 读取视频帧

            // 将彩色图像转换为灰度图像以加快处理速度
            cv::Mat grayFrame;
            cv::cvtColor(frame, grayFrame, cv::COLOR_BGR2GRAY);

            // 对图像进行人脸检测
            std::vector<cv::Rect> faces;
            faceCascade.detectMultiScale(grayFrame, faces, 1.1, 3, 0, cv::Size(30, 30));

            // 在图像上绘制人脸边界框
            for (size_t i = 0; i < faces.size(); i++)
            {
                cv::rectangle(frame, faces[i], cv::Scalar(0, 255, 0), 2);
            }

            // 显示结果图像
            cv::imshow("Face Detection", frame);

            // 按下ESC键退出循环
            if (cv::waitKey(1) == 27)
                break;
        }

        // 释放摄像头和窗口资源
        capture.release();
        cv::destroyAllWindows();





}*/
/*void OpencvMo::face_demo(Mat& image) {
    std::string root_dir = "D:/face_detector/";
    dnn::Net net = dnn::readNetFromTensorflow(root_dir + "opencv_face_detector_uint8.pb", root_dir + "opencv_face_detector.pbtxt");
    if (net.empty()) {
        std::cerr << "Error: Could not load the model." << std::endl;
        return;
    }

    VideoCapture capture(0);
    if (!capture.isOpened()) {
        std::cerr << "Error: Could not open video file." << std::endl;
        return;
    }

    Mat frame;
    while (true) {
        capture.read(frame);
        if (frame.empty()) {
            break;
        }
        Mat blob = dnn::blobFromImage(frame, 1.0, Size(300, 300), Scalar(104, 177, 123), false, false);
        net.setInput(blob);
        Mat probs = net.forward();
        Mat detectionMat(probs.size[2], probs.size[3], CV_32F, probs.ptr<float>());
        for (int i = 0; i < detectionMat.rows; i++) {
            float confidence = detectionMat.at<float>(i, 2);
            if (confidence > 0.5) {
                int x1 = static_cast<int>(detectionMat.at<float>(i, 3) * frame.cols);
                int y1 = static_cast<int>(detectionMat.at<float>(i, 4) * frame.rows);
                int x2 = static_cast<int>(detectionMat.at<float>(i, 5) * frame.cols);
                int y2 = static_cast<int>(detectionMat.at<float>(i, 6) * frame.rows);
                Rect box(x1, y1, x2 - x1, y2 - y1);
                rectangle(frame, box, Scalar(0, 0, 255), 2, 8, 0);
            }
        }
        imshow("人脸检测展示", frame); // 使用英文标题
        int c = waitKey(1);
        if (c == 27) {
            break;
        }
    }
}
*/
